package com.tanvir.sdl.client;

import java.io.File;
import java.io.Serializable;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.htmlparser.Node;
import org.htmlparser.tags.LinkTag;


public class MainThread
    implements Runnable, Serializable {
    private static Logger logger = Logger.getLogger(MainThread.class.getPackage().getName());
    private String url;
    private File baseDir;
    private ExecutorService es;

    public MainThread(String url, File baseDir) {
        super();
        this.url = url;
        this.baseDir = baseDir;
        es = Executors.newFixedThreadPool(5);
    }

    public void run() {
        try {
            Node[] list = MoviesFilter.list(url);
            for (Node movie : list) {
                String movieName = movie.getFirstChild().getText();
                //logger.log(Level.INFO, "Movie Name : {0}", movieName);
                if (movie instanceof LinkTag) {
                    LinkTag lm = (LinkTag)movie;
                    Node[] sList = SongsFilter.list(lm.extractLink());
                    File mf = new File(baseDir, movieName);
                    for (Node song : sList) {
                        String songName = song.getFirstChild().getText();
                        if (songName != null && !songName.endsWith(".mp3")) {
                            songName = songName.trim() + ".mp3";
                        }
                        //logger.log(Level.INFO, "Song : {0}", songName);
                        if (song instanceof LinkTag) {
                            LinkTag ls = (LinkTag)song;
                            String link = DownloadFilter.link(ls.extractLink());
                            DLThread dlt = new DLThread(link, songName, mf);
                            es.submit(dlt);
                        }
                    }
                }
            }
            es.shutdown();
            logger.log(Level.INFO, "Waiting for shutdown");
            while (!es.awaitTermination(10, TimeUnit.SECONDS)) {
            }
        } catch (Exception ex) {
            logger.log(Level.SEVERE, "error - ", ex);
            shutdownAndAwaitTermination();
        }
    }

    public void shutdownAndAwaitTermination() {
        logger.log(Level.INFO, "force shutdown");
        es.shutdown(); // Disable new tasks from being submitted
        try {
            // Wait a while for existing tasks to terminate
            logger.log(Level.INFO, "Waiting for shutdown");
            if (!es.awaitTermination(10, TimeUnit.SECONDS)) {
                es.shutdownNow(); // Cancel currently executing tasks
                // Wait a while for tasks to respond to being cancelled
                if (!es.awaitTermination(60, TimeUnit.SECONDS))
                    logger.log(Level.WARNING, "Pool did not terminate");
            }
        } catch (InterruptedException ie) {
            // (Re-)Cancel if current thread also interrupted
            es.shutdownNow();
            // Preserve interrupt status
            Thread.currentThread().interrupt();
        }
    }
}
